package com.game.battleship.db;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;

public class DbAdapter {

	private SQLiteDatabase db;
	private Context context;
	private DbHelper dbHelper;
	
	public DbAdapter(Context context) {
		this.context = context;
		this.dbHelper = new DbHelper(context);
	}
	
	public Map<String, String> getUser(String username) throws SQLiteException {
		HashMap<String, String> map = new HashMap<String, String>();
		db = dbHelper.getReadableDatabase();
		Cursor cursor = db.query(UsersTable.TABLE_NAME, 
						null, 
						UsersTable.USER_USERNAME + " = '" + username + "'", 
						null, null, null, null);
		
		if (cursor != null && cursor.getCount() > 0) {
			cursor.moveToFirst();
			map.put("id", cursor.getLong(0) + "");
			map.put("username", cursor.getString(1) + "");
			map.put("password", cursor.getString(2) + "");
			map.put("score", cursor.getInt(3) + "");
			map.put("nextStage", cursor.getInt(4) + "");
			cursor.close();
			dbHelper.close();
			return map;
		}
		else {
			map = null;
			cursor.close();
			dbHelper.close();
			return map;
		}
		
	}
	
	public ArrayList<Map<String, String>> getUsers() throws SQLiteException {
		ArrayList<Map<String, String>> users = new ArrayList<Map<String, String>>();
		db = dbHelper.getReadableDatabase();
		Cursor cursor = db.query(UsersTable.TABLE_NAME, 
						null, 
						null, null, null, null, UsersTable.USER_SCORES + " DESC");
		
		if (cursor != null && cursor.getCount() > 0) {
			int count = cursor.getCount();
			for (int i=0;i<count;++i) {
				cursor.moveToNext();
				HashMap<String, String> map = new HashMap<String, String>();
				map.put("id", cursor.getLong(0) + "");
				map.put("username", cursor.getString(1) + "");
				map.put("password", cursor.getString(2) + "");
				map.put("score", cursor.getInt(3) + "");
				map.put("nextStage", cursor.getInt(4) + "");
				users.add(map);
			}			
			cursor.close();
			dbHelper.close();
			return users;
		}
		else {
			cursor.close();
			dbHelper.close();
			return users;
		}
		
	}
	
	public boolean authenticate(String username, String password) throws SQLiteException {
		db = dbHelper.getReadableDatabase();
		Cursor cursor = db.query(UsersTable.TABLE_NAME, 
						null, 
						UsersTable.USER_USERNAME + " = '" + username + "' and " + UsersTable.USER_PASSWORD + " = '" + password + "'", 
						null, null, null, null);
		boolean succeeded;
		if (cursor == null) succeeded = false;
		else if (cursor.getCount() <= 0) {
//			System.out.println(cursor.getCount());
			succeeded = false;
			cursor.close();
		}
		else succeeded = true;
		dbHelper.close();
		return succeeded;
	}
	
	public long insertUser(String username, String password, int scores, int nextStageID) throws SQLiteException {
		ContentValues cv = createUserContentValues(username, password, scores, nextStageID);
		db = dbHelper.getWritableDatabase();
		long newlyInsertedID = db.insert(UsersTable.TABLE_NAME, null, cv);
		dbHelper.close();
		return newlyInsertedID;
	}
	
	public int updateUserByID(long id, String username, String password, int scores, int nextStageID) throws SQLiteException {
		ContentValues cv = createUserContentValues(username, password, scores, nextStageID);
		db = dbHelper.getWritableDatabase();
		int nRowsAffected = db.update(UsersTable.TABLE_NAME, cv, UsersTable.USER_ID + " = " + id, null);
		dbHelper.close();
		return nRowsAffected;
	}
	
	public int updateUserByUsername(String username, String password, int scores, int nextStageID) throws SQLiteException {
		ContentValues cv = createUserContentValues(username, password, scores, nextStageID);
		db = dbHelper.getWritableDatabase();
		int nRowsAffected = db.update(UsersTable.TABLE_NAME, cv, UsersTable.USER_USERNAME + " = '" + username + "'", null);
		dbHelper.close();
		return nRowsAffected;
	}
	
	public int deleteUser(long id) throws SQLiteException {
		db = dbHelper.getReadableDatabase();
		int nRowsAffected = db.delete(UsersTable.TABLE_NAME, UsersTable.USER_ID + " = " + id, null);
		db.close();
		return nRowsAffected;
	}
	
	public int deleteUser(String username) throws SQLiteException {
		db = dbHelper.getReadableDatabase();
		int nRowsAffected = db.delete(UsersTable.TABLE_NAME, UsersTable.USER_USERNAME + " = '" + username + "'", null);
		db.close();
		return nRowsAffected;
	}
	
	public long insertStage(byte[] map) throws SQLiteException {
		ContentValues cv = createStageContentValues(map);
		db = dbHelper.getWritableDatabase();
		long newlyInsertedID = db.insert(StagesTable.TABLE_NAME, null, cv);
		dbHelper.close();
		return newlyInsertedID;
	}
	
	public int updateStageOfID(long id, byte[] map) throws SQLiteException {
		ContentValues cv = createStageContentValues(map);
		db = dbHelper.getWritableDatabase();
		int nRowsAffected = db.update(StagesTable.TABLE_NAME, cv, StagesTable.STAGE_ID + " = " + id, null);
		dbHelper.close();
		return nRowsAffected;
	}
	
	public int deleteStage(long id) throws SQLiteException {
		db = dbHelper.getReadableDatabase();
		int nRowsAffected = db.delete(StagesTable.TABLE_NAME, StagesTable.STAGE_ID + " = " + id, null);
		db.close();
		return nRowsAffected;
	}
	
	private ContentValues createStageContentValues(byte[] map) {
		ContentValues values = new ContentValues();
		values.put(StagesTable.STAGE_MAP, map);
		return values;
	}
	
	private ContentValues createUserContentValues(String username, String password, int scores, int nextStageID) {
		ContentValues values = new ContentValues();
		values.put(UsersTable.USER_USERNAME, username);
		values.put(UsersTable.USER_PASSWORD, password);
		values.put(UsersTable.USER_SCORES, scores);
		values.put(UsersTable.USER_NEXT_STAGE_ID, nextStageID);
		return values;
	}

	public Context getContext() {
		return context;
	}
}
